﻿Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.ComponentModel

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
<DefaultEvent("RatingChanged")> _
Public Class StarRateBox
    Inherits System.Windows.Forms.UserControl

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Me.SetStyle(Windows.Forms.ControlStyles.SupportsTransparentBackColor, True)
        Me.SetStyle(Windows.Forms.ControlStyles.OptimizedDoubleBuffer, True)
        Me.SetStyle(Windows.Forms.ControlStyles.ResizeRedraw, True)
        Me.ResizeRedraw = True

    End Sub

#Region "Designer Generated Code"
    'UserControl overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private WithEvents components As System.Windows.Forms.UserControl

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
        Me.components = New System.Windows.Forms.UserControl()
        Me.SuspendLayout()
        '
        'components
        '
        Me.components.Location = New System.Drawing.Point(0, 0)
        Me.components.Name = "StarRateBox"
        Me.components.Size = New System.Drawing.Size(100, 23)
        Me.components.TabIndex = 0
        Me.BackColor = SystemColors.InactiveBorder
        '
        'VerticalContainerLabel
        '
        Me.Name = "StarRateBox"
        Me.ResumeLayout(False)
    End Sub
#End Region

#Region "Declarations"
    Private iNormalBorderDark As Color = Color.FromArgb(112, 112, 112)
    'Public Property NormalBorderDark As Color
    '    Get
    '        Return Me.iNormalBorderDark
    '    End Get
    '    Set(value As Color)
    '        Me.iNormalBorderDark = value
    '    End Set
    'End Property
    Private iNormalBorderLight1 As Color = Color.FromArgb(207, 207, 207)
    'Public Property NormalBorderLight1 As Color
    '    Get
    '        Return Me.iNormalBorderLight1
    '    End Get
    '    Set(value As Color)
    '        Me.iNormalBorderLight1 = value
    '    End Set
    'End Property
    Private iNormalBorderLight2 As Color = Color.FromArgb(242, 242, 242)
    'Public Property NormalBorderLight2 As Color
    '    Get
    '        Return Me.iNormalBorderLight2
    '    End Get
    '    Set(value As Color)
    '        Me.iNormalBorderLight2 = value
    '    End Set
    'End Property
    Private iActiveBorderDark As Color = Color.FromArgb(60, 127, 177)
    'Public Property ActiveBorderDark As Color
    '    Get
    '        Return Me.iActiveBorderDark
    '    End Get
    '    Set(value As Color)
    '        Me.iActiveBorderDark = value
    '    End Set
    'End Property
    Private iActiveBorderLight1 As Color = Color.FromArgb(167, 217, 245)
    'Public Property ActiveBorderLight1 As Color
    '    Get
    '        Return Me.iActiveBorderLight1
    '    End Get
    '    Set(value As Color)
    '        Me.iActiveBorderLight1 = value
    '    End Set
    'End Property
    Private iActiveBorderLight2 As Color = Color.FromArgb(234, 246, 253)
    'Public Property ActiveBorderLight2 As Color
    '    Get
    '        Return Me.iActiveBorderLight2
    '    End Get
    '    Set(value As Color)
    '        Me.iActiveBorderLight2 = value
    '    End Set
    'End Property
    Private iRatingStarImageGray As Image = My.Resources.Icon_Star_Gray_32
    Public Property RatingStarImageGray As Image
        Get
            Return Me.iRatingStarImageGray
        End Get
        Set(value As Image)
            Me.iRatingStarImageGray = value
            Me.Invalidate()
        End Set
    End Property
    Private iRatingStarImageColor As Image = My.Resources.Icon_Star_Normal_32
    Public Property RatingStarImageColor As Image
        Get
            Return Me.iRatingStarImageColor
        End Get
        Set(value As Image)
            Me.iRatingStarImageColor = value
            Me.Invalidate()
        End Set
    End Property
    Dim iRating As Integer = 0
    Public Property Rating As Integer
        Get
            Return Me.iRating
        End Get
        Set(value As Integer)
            If value < 7 Then
                Me.iRating = value
                Me.Invalidate()
            Else
                MsgBox("Only values between 0 and 6 are accepted")
            End If
        End Set
    End Property

    Dim offBitmap As Bitmap = Nothing
    Dim iMouseOverRating As Integer = 0
    Public Event RatingChanged(Sender As Object, e As RatingChagedEventArgs)
    Dim iMouseOver As Boolean
    Dim sRect1 As Rectangle = Nothing
    Dim sRect2 As Rectangle = Nothing
    Dim sRect3 As Rectangle = Nothing
    Dim sRect4 As Rectangle = Nothing
    Dim sRect5 As Rectangle = Nothing
    Dim sRect6 As Rectangle = Nothing
#End Region

    Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
        'MyBase.OnPaint(e)

        If Me.offBitmap Is Nothing Then
            Me.offBitmap = New Bitmap(Me.ClientRectangle.Width, Me.ClientRectangle.Height)
        End If
        Dim g As Graphics = Graphics.FromImage(Me.offBitmap)

        'Graphics helper
        Dim gh As New GraphicsHelper

        'Background
        If Me.ParentForm IsNot Nothing Then
            g.FillRectangle(New SolidBrush(Me.ParentForm.BackColor), Me.ClientRectangle)
        End If

        'Draw dark border
        Dim borderRect As New Rectangle(Me.ClientRectangle.Left, _
                                        Me.ClientRectangle.Top, _
                                        Me.ClientRectangle.Width - 1, _
                                        Me.ClientRectangle.Height - 1)

        Dim iBorderDarkPen As Pen = Nothing
        If iMouseOver Then
            iBorderDarkPen = New Pen(Me.iActiveBorderDark)
        Else
            iBorderDarkPen = New Pen(Me.iNormalBorderDark)
        End If
        g.DrawPath(iBorderDarkPen, gh.GetRoundCornerPathForRectangle(borderRect))

        'Draw light border
        Dim borderRect2 As New Rectangle(borderRect.Left + 2, _
                                                    borderRect.Top + 2, _
                                                    borderRect.Width - 4, _
                                                    borderRect.Height - 4)
        Dim iBorderPenLight As Pen = Nothing
        If iMouseOver Then
            iBorderPenLight = New Pen(New LinearGradientBrush(borderRect2, _
                                                              Me.iActiveBorderLight2, _
                                                              Me.iActiveBorderLight1, _
                                                              LinearGradientMode.ForwardDiagonal))
        Else
            iBorderPenLight = New Pen(New LinearGradientBrush(borderRect2, _
                                                              Me.iNormalBorderLight2, _
                                                              Me.iNormalBorderLight1, _
                                                              LinearGradientMode.ForwardDiagonal))
        End If
        g.DrawPath(iBorderPenLight, gh.GetRoundCornerPathForRectangle(borderRect2))

        If sRect1 = Rectangle.Empty Then
            Dim sWidth As Integer = Me.Size.Height - 9
            sRect1 = New Rectangle(Me.ClientRectangle.X + 4, Me.ClientRectangle.Y + 4, sWidth, sWidth)
            sRect2 = New Rectangle(sRect1.X + sWidth + 1, Me.ClientRectangle.Y + 4, sWidth, sWidth)
            sRect3 = New Rectangle(sRect2.X + sWidth + 1, Me.ClientRectangle.Y + 4, sWidth, sWidth)
            sRect4 = New Rectangle(sRect3.X + sWidth + 1, Me.ClientRectangle.Y + 4, sWidth, sWidth)
            sRect5 = New Rectangle(sRect4.X + sWidth + 1, Me.ClientRectangle.Y + 4, sWidth, sWidth)
            sRect6 = New Rectangle(sRect5.X + sWidth + 1, Me.ClientRectangle.Y + 4, sWidth, sWidth)
        End If

        If Me.iMouseOver = False Then
            Select Case Me.iRating
                Case Is = 1
                    g.DrawImage(Me.iRatingStarImageColor, sRect1)
                    g.DrawImage(Me.iRatingStarImageGray, sRect2)
                    g.DrawImage(Me.iRatingStarImageGray, sRect3)
                    g.DrawImage(Me.iRatingStarImageGray, sRect4)
                    g.DrawImage(Me.iRatingStarImageGray, sRect5)
                    g.DrawImage(Me.iRatingStarImageGray, sRect6)
                Case Is = 2
                    g.DrawImage(Me.iRatingStarImageColor, sRect1)
                    g.DrawImage(Me.iRatingStarImageColor, sRect2)
                    g.DrawImage(Me.iRatingStarImageGray, sRect3)
                    g.DrawImage(Me.iRatingStarImageGray, sRect4)
                    g.DrawImage(Me.iRatingStarImageGray, sRect5)
                    g.DrawImage(Me.iRatingStarImageGray, sRect6)
                Case Is = 3
                    g.DrawImage(Me.iRatingStarImageColor, sRect1)
                    g.DrawImage(Me.iRatingStarImageColor, sRect2)
                    g.DrawImage(Me.iRatingStarImageColor, sRect3)
                    g.DrawImage(Me.iRatingStarImageGray, sRect4)
                    g.DrawImage(Me.iRatingStarImageGray, sRect5)
                    g.DrawImage(Me.iRatingStarImageGray, sRect6)
                Case Is = 4
                    g.DrawImage(Me.iRatingStarImageColor, sRect1)
                    g.DrawImage(Me.iRatingStarImageColor, sRect2)
                    g.DrawImage(Me.iRatingStarImageColor, sRect3)
                    g.DrawImage(Me.iRatingStarImageColor, sRect4)
                    g.DrawImage(Me.iRatingStarImageGray, sRect5)
                    g.DrawImage(Me.iRatingStarImageGray, sRect6)
                Case Is = 5
                    g.DrawImage(Me.iRatingStarImageColor, sRect1)
                    g.DrawImage(Me.iRatingStarImageColor, sRect2)
                    g.DrawImage(Me.iRatingStarImageColor, sRect3)
                    g.DrawImage(Me.iRatingStarImageColor, sRect4)
                    g.DrawImage(Me.iRatingStarImageColor, sRect5)
                    g.DrawImage(Me.iRatingStarImageGray, sRect6)
                Case Is = 6
                    g.DrawImage(Me.iRatingStarImageColor, sRect1)
                    g.DrawImage(Me.iRatingStarImageColor, sRect2)
                    g.DrawImage(Me.iRatingStarImageColor, sRect3)
                    g.DrawImage(Me.iRatingStarImageColor, sRect4)
                    g.DrawImage(Me.iRatingStarImageColor, sRect5)
                    g.DrawImage(Me.iRatingStarImageColor, sRect6)
                Case Else
                    g.DrawImage(Me.iRatingStarImageGray, sRect1)
                    g.DrawImage(Me.iRatingStarImageGray, sRect2)
                    g.DrawImage(Me.iRatingStarImageGray, sRect3)
                    g.DrawImage(Me.iRatingStarImageGray, sRect4)
                    g.DrawImage(Me.iRatingStarImageGray, sRect5)
                    g.DrawImage(Me.iRatingStarImageGray, sRect6)
            End Select
        Else
            Select Case Me.iMouseOverRating
                Case Is = 1
                    g.DrawImage(Me.iRatingStarImageColor, sRect1)
                    g.DrawImage(Me.iRatingStarImageGray, sRect2)
                    g.DrawImage(Me.iRatingStarImageGray, sRect3)
                    g.DrawImage(Me.iRatingStarImageGray, sRect4)
                    g.DrawImage(Me.iRatingStarImageGray, sRect5)
                    g.DrawImage(Me.iRatingStarImageGray, sRect6)
                Case Is = 2
                    g.DrawImage(Me.iRatingStarImageColor, sRect1)
                    g.DrawImage(Me.iRatingStarImageColor, sRect2)
                    g.DrawImage(Me.iRatingStarImageGray, sRect3)
                    g.DrawImage(Me.iRatingStarImageGray, sRect4)
                    g.DrawImage(Me.iRatingStarImageGray, sRect5)
                    g.DrawImage(Me.iRatingStarImageGray, sRect6)
                Case Is = 3
                    g.DrawImage(Me.iRatingStarImageColor, sRect1)
                    g.DrawImage(Me.iRatingStarImageColor, sRect2)
                    g.DrawImage(Me.iRatingStarImageColor, sRect3)
                    g.DrawImage(Me.iRatingStarImageGray, sRect4)
                    g.DrawImage(Me.iRatingStarImageGray, sRect5)
                    g.DrawImage(Me.iRatingStarImageGray, sRect6)
                Case Is = 4
                    g.DrawImage(Me.iRatingStarImageColor, sRect1)
                    g.DrawImage(Me.iRatingStarImageColor, sRect2)
                    g.DrawImage(Me.iRatingStarImageColor, sRect3)
                    g.DrawImage(Me.iRatingStarImageColor, sRect4)
                    g.DrawImage(Me.iRatingStarImageGray, sRect5)
                    g.DrawImage(Me.iRatingStarImageGray, sRect6)
                Case Is = 5
                    g.DrawImage(Me.iRatingStarImageColor, sRect1)
                    g.DrawImage(Me.iRatingStarImageColor, sRect2)
                    g.DrawImage(Me.iRatingStarImageColor, sRect3)
                    g.DrawImage(Me.iRatingStarImageColor, sRect4)
                    g.DrawImage(Me.iRatingStarImageColor, sRect5)
                    g.DrawImage(Me.iRatingStarImageGray, sRect6)
                Case Is = 6
                    g.DrawImage(Me.iRatingStarImageColor, sRect1)
                    g.DrawImage(Me.iRatingStarImageColor, sRect2)
                    g.DrawImage(Me.iRatingStarImageColor, sRect3)
                    g.DrawImage(Me.iRatingStarImageColor, sRect4)
                    g.DrawImage(Me.iRatingStarImageColor, sRect5)
                    g.DrawImage(Me.iRatingStarImageColor, sRect6)
                Case Else
                    g.DrawImage(Me.iRatingStarImageGray, sRect1)
                    g.DrawImage(Me.iRatingStarImageGray, sRect2)
                    g.DrawImage(Me.iRatingStarImageGray, sRect3)
                    g.DrawImage(Me.iRatingStarImageGray, sRect4)
                    g.DrawImage(Me.iRatingStarImageGray, sRect5)
                    g.DrawImage(Me.iRatingStarImageGray, sRect6)
            End Select
        End If

        e.Graphics.DrawImage(Me.offBitmap, Me.ClientRectangle)

    End Sub

    Protected Overrides Sub OnResize(e As System.EventArgs)
        MyBase.OnResize(e)

        'Calculate propotional width
        Dim sWidth As Integer = Me.Size.Height - 9
        Dim pWidth As Integer = ((sWidth) * 6) + 14

        'Set new size
        If Me.Size.Width <> pWidth Then
            Me.Size = New Size(pWidth, Me.Size.Height)
            sRect1 = New Rectangle(Me.ClientRectangle.X + 4, Me.ClientRectangle.Y + 4, sWidth, sWidth)
            sRect2 = New Rectangle(sRect1.X + sWidth + 1, Me.ClientRectangle.Y + 4, sWidth, sWidth)
            sRect3 = New Rectangle(sRect2.X + sWidth + 1, Me.ClientRectangle.Y + 4, sWidth, sWidth)
            sRect4 = New Rectangle(sRect3.X + sWidth + 1, Me.ClientRectangle.Y + 4, sWidth, sWidth)
            sRect5 = New Rectangle(sRect4.X + sWidth + 1, Me.ClientRectangle.Y + 4, sWidth, sWidth)
            sRect6 = New Rectangle(sRect5.X + sWidth + 1, Me.ClientRectangle.Y + 4, sWidth, sWidth)
            Me.Invalidate()
        End If

    End Sub

    Protected Overrides Sub OnMouseUp(e As System.Windows.Forms.MouseEventArgs)
        MyBase.OnMouseUp(e)
        If sRect1.Contains(e.Location) And Me.iRating <> 1 Then
            Me.iRating = 1
            RaiseEvent RatingChanged(Me, New RatingChagedEventArgs(Me.iRating))
        ElseIf sRect2.Contains(e.Location) And Me.iRating <> 2 Then
            Me.iRating = 2
            RaiseEvent RatingChanged(Me, New RatingChagedEventArgs(Me.iRating))
        ElseIf sRect3.Contains(e.Location) And Me.iRating <> 3 Then
            Me.iRating = 3
            RaiseEvent RatingChanged(Me, New RatingChagedEventArgs(Me.iRating))
        ElseIf sRect4.Contains(e.Location) And Me.iRating <> 4 Then
            Me.iRating = 4
            RaiseEvent RatingChanged(Me, New RatingChagedEventArgs(Me.iRating))
        ElseIf sRect5.Contains(e.Location) And Me.iRating <> 5 Then
            Me.iRating = 5
            RaiseEvent RatingChanged(Me, New RatingChagedEventArgs(Me.iRating))
        ElseIf sRect6.Contains(e.Location) And Me.iRating <> 6 Then
            Me.iRating = 6
            RaiseEvent RatingChanged(Me, New RatingChagedEventArgs(Me.iRating))
        End If
    End Sub

    Protected Overrides Sub OnMouseMove(e As System.Windows.Forms.MouseEventArgs)
        MyBase.OnMouseMove(e)
        'Dim pt1 As Point = e.Location
        'Dim pt2 As Point = Me.PointToScreen(e.Location)
        'Debug.Print("Mouse: " & e.Location.ToString)
        'Debug.Print("sRect: " & sRect1.ToString)
        If sRect1.Contains(e.Location) And Me.iMouseOverRating <> 1 Then
            Me.iMouseOverRating = 1
            Me.Invalidate()
        ElseIf sRect2.Contains(e.Location) And Me.iMouseOverRating <> 2 Then
            Me.iMouseOverRating = 2
            Me.Invalidate()
        ElseIf sRect3.Contains(e.Location) And Me.iMouseOverRating <> 3 Then
            Me.iMouseOverRating = 3
            Me.Invalidate()
        ElseIf sRect4.Contains(e.Location) And Me.iMouseOverRating <> 4 Then
            Me.iMouseOverRating = 4
            Me.Invalidate()
        ElseIf sRect5.Contains(e.Location) And Me.iMouseOverRating <> 5 Then
            Me.iMouseOverRating = 5
            Me.Invalidate()
        ElseIf sRect6.Contains(e.Location) And Me.iMouseOverRating <> 6 Then
            Me.iMouseOverRating = 6
            Me.Invalidate()
        End If

    End Sub

    Protected Overrides Sub OnMouseEnter(e As System.EventArgs)
        MyBase.OnMouseEnter(e)
        If Me.iMouseOver = False Then
            Me.iMouseOver = True
            Me.Invalidate()
        End If
    End Sub

    Protected Overrides Sub OnMouseLeave(e As System.EventArgs)
        MyBase.OnMouseLeave(e)
        If Me.iMouseOver = True Then
            Me.iMouseOver = False
            Me.Invalidate()
        End If
    End Sub

End Class
Public Class RatingChagedEventArgs
    Inherits EventArgs

    Private iRating As Integer
    Public Property Rating As Integer
        Get
            Return Me.iRating
        End Get
        Set(value As Integer)
            Me.iRating = value
        End Set
    End Property

    Private Sub New()
    End Sub
    Public Sub New(Rating As Integer)
        Me.iRating = Rating
    End Sub

End Class